from typing import Optional
from common.enum.form_items_key import FormItemsKey
from common.enum.stock_risk_level_enum import RiskLevelEnum
from service.das.data_map_das import DataDictionaryDas
from service.setting_service import DataDictionaryService
from .das.stock_monitor_das import StockDas, AntMonitorStock
from .das.stock_day_das import StockDateDayDas
from .das.tushare_pool import getDayStock, getRealTime
from datetime import datetime, timedelta
from .das.sina_das import get_stock_info
from dto.stock_info_monitor import AntMonitorStockInfo


class StockMainService:
    def listSelfStock(self, sort_by="focus_level"):
        """
        获取所有股票列表，并根据不同的排序方式返回。
        :param sort_by: 排序方式，'focus_level' 或 'risk_level'
        :return: 股票列表
        """
        stock_das = StockDas()
        # 根据排序方式选择排序
        if sort_by == "risk_level":
            sorted_stocks = stock_das.get_stocks_by_risk_level()  # 按照风险等级排序
        elif sort_by == "focus_level":
            sorted_stocks = stock_das.get_stocks_by_focus_level()  # 按照关注等级排序
        return sorted_stocks

    def get_risk_level_description(self, risk_level: Optional[int]) -> str:
        """
        根据风险等级返回描述。
        :param risk_level: 风险等级（1-10）
        :return: 风险等级描述
        """
        return RiskLevelEnum.get_description(risk_level)

    def getAllStockListSample(self):
        stock_das = StockDas()
        stockList = stock_das.get_stocks()
        stockInfo = [f"{stock.stock_name} & {stock.stock_code}" for stock in stockList]
        return stockInfo

    def getAllStockList():
        stock_das = StockDas()
        stockList = stock_das.get_stocks()
        return stockList

    def saveMonitorStock(stockInfo: AntMonitorStockInfo):
        # 获取今天的日期
        today = datetime.today()
        # 获取一年前的日期
        dataMap = DataDictionaryDas()
        result = dataMap.get_item_by_form_enum(FormItemsKey.TUSHARE_INIT_DAY)
        days = 90  # 默认值
        if result and hasattr(result, "dict_value"):
            try:
                days = int(result.dict_value)
            except (ValueError, TypeError):
                print(f"警告: 无法将 {result.dict_value} 转换为整数，使用默认值 {days}")

        ten_year_ago = today - timedelta(days=days)

        # 保存 Stock 数据
        stock_das = StockDas()
        stock = stock_das.get_stocks_byCode(stockInfo.stock_code)
        if stock:
            print(f"数据已存在,无需添加")
            return

        # 聚合出股票名称
        stockDetail = get_stock_info(stockInfo.stock_code)
        stockInfo.stock_name = stockDetail.name if stockDetail else "未知股票"

        # 计算额外参数

        stock_das.add_stock(stockInfo)

        today_str = today.strftime("%Y%m%d")
        one_year_ago_str = ten_year_ago.strftime("%Y%m%d")

        df = getDayStock(stockInfo.stock_code, one_year_ago_str, today_str)
        print(f"开始保存拉取到到当个股票的数据")
        StockDateDayDas.add_stock(df)

    def updateMonitorStock(stockInfo: AntMonitorStockInfo):
        stock_das = StockDas()
        stock_das.update_stock_bycode(stockInfo)

    def deleteOneStock(stockCode):
        # 删除历史的 StockMonitor 的信息
        stock_das = StockDas()
        stock = stock_das.delete_bycode(stockCode)

        # 删除历史的 每日数据
        StockDateDayDas.delete_bycode(stockCode)

    def getByStockCode(stockCode):
        stock_das = StockDas()
        stock_record = stock_das.get_stocks_byCode(stockCode)
        return AntMonitorStockInfo(
            stock_code=stock_record.stock_code,
            stock_name=stock_record.stock_name,
            stock_focus_level=stock_record.stock_focus_level,
            stock_risk_level=stock_record.stock_risk_level,
            stock_current_number=stock_record.stock_current_number,
            stock_max_number=stock_record.stock_max_number,
            monitor_origin_price=stock_record.monitor_origin_price,
            monitor_current_price=stock_record.monitor_current_price,
            monitor_income_ratio=stock_record.monitor_income_ratio,
            monitor_income_money=stock_record.monitor_income_money,
            monitor_target_ratio=stock_record.monitor_target_ratio,
            monitor_stop_ratio=stock_record.monitor_stop_ratio,
            stock_status=stock_record.stock_status,
            stock_category=stock_record.stock_category,
            stock_tag=stock_record.stock_tag,
            next_advice=stock_record.stock_next_advice,
            month_up_day=stock_record.month_up_day,
            week_up_day=stock_record.week_up_day,
            other_info=stock_record.other_info,
        )

    def getRealTimeStock(stockCode):
        print(f"当前处理的股票{stockCode}")
        df = getRealTime(stockCode)
        print(f"获取到股票代码:{df}")
        result = [["stock_price", "type", "time"]]
        if df is not None:
            for index, row in df.iterrows():
                result.append(
                    [float(row["PRICE"]), "real", int(row["TIME"].replace(":", ""))]
                )

        return result


class StockCalculateService:

    def calculate_monitor_values(self, stockInfo: AntMonitorStockInfo):

        """
        计算 monitor_income_money 和 monitor_current_price

        :param stock_code: 股票代码
        :param monitor_income_ratio: 收益率
        :param stock_current_number: 当前股票数量
        :param kwargs: 其他字段（兼容入参对象）
        :return: 计算后的值
        """
        # 获取近期日线数据
        try:
            daily_data = self.pro.daily(ts_code=stockInfo.stock_code, limit=1)
            if daily_data.empty:
                raise ValueError(f"No daily data found for stock code: {stockInfo.stock_code}")

            # 获取当前股价
            monitor_current_price = daily_data.iloc[0]["close"]

            # 计算 monitor_income_money
            monitor_income_money = (
                stockInfo.stock_current_number * monitor_current_price * stockInfo.monitor_income_ratio
            )

            return {
                "monitor_current_price": monitor_current_price,
                "monitor_income_money": monitor_income_money,
            }
        except Exception as e:
            print(f"Error calculating monitor values: {e}")
            return {"monitor_current_price": None, "monitor_income_money": None}
